package com.yuan.gather.service.impl;

import com.yuan.gather.model.GatherDetail;
import com.yuan.gather.model.GatherDetailOutput;
import com.yuan.gather.model.GatherDetailVariable;
import com.yuan.gather.model.GatherGroup;
import com.yuan.gather.model.GatherXmlBean;
import com.yuan.gather.model.GatherXmlCategoryBean;
import com.yuan.gather.model.GatherXmlMainCategoryBean;
import com.yuan.gather.service.FileChangeService;
import com.yuan.gather.utils.CommUtils;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import javax.annotation.PostConstruct;
import javax.xml.bind.JAXBContext;
import javax.xml.bind.Unmarshaller;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;

/**
 * (采集)指标维护类
 *
 * @author zhaoff
 */
@Slf4j
@Component(value = "gatherCenter")
public class GatherCenter {

    /**
     * 文件变更监控服务
     */
    @Autowired
    private FileChangeService fileChangeService;

    /**
     * 采集配置文件对应的实体
     */
    private GatherXmlBean dataCenter;

    /**
     * 预巡检项所在的组
     */
    public static final String PRE_REQUISITE_GROUP = "_prerequisite";

    /**
     * CentOS 5
     */
    public static final String CENTOS_5 = "L5";

    /**
     * CentOS 6
     */
    public static final String CENTOS_6 = "L6";

    /**
     * 采集项require字段分隔符
     */
    private static final String REQUIRE_SPLIT = ",";

    /**
     * 采集配置文件存放的目录
     */
    public static final String gatherConfigDir = CommUtils.getDataDir().concat(File.separator).concat("gather")
            .concat(File.separator);

    /**
     * 当采集的原始输出太长的时候，采集结果放到文本文件中存放的目录
     */
    public static final String gatherLogDir = CommUtils.getDataDir().concat(File.separator).concat("share")
            .concat(File.separator).concat("gather").concat(File.separator).concat("output").concat(File.separator);

    /**
     * 操作符map
     */
    public static final Map<String, String> opMap = new HashMap<>();

    /**
     * 采集类型--不常变化项
     */
    public static final Integer TYPE_INFREQUENT_CHANGE_ITEM = 2;

    /**
     * 所有资产类型对应的采集任务类型
     */
    private final Map<Long, Set<Integer>> collectTypesBySystype = new HashMap<>();

    /**
     * 初始化操作符字典
     */
    private void initOpMap() {
        opMap.put("==", "等于");
        opMap.put("!=", "不等于");
        opMap.put("<", "小于");
        opMap.put(">", "大于");
        opMap.put("<=", "小于等于");
        opMap.put(">=", "大于等于");
        opMap.put("v<", "小于");
        opMap.put("v>", "大于");
        opMap.put("v<=", "小于等于");
        opMap.put("v>=", "大于等于");
        opMap.put("LIKE", "包含");
        opMap.put("NOTLIKE", "不包含");
        opMap.put("IN", "包含");
        opMap.put("NOTIN", "不包含");
        opMap.put("NOP", "任何");
        opMap.put("o==", "等于");
        opMap.put("o!=", "不等于");
        opMap.put("o<", "小于");
        opMap.put("o>", "大于");
        opMap.put("o<=", "小于等于");
        opMap.put("o>=", "大于等于");
        opMap.put("oIN", "包含");
        opMap.put("oNOTIN", "不包含");
        opMap.put("s==", "等于");
        opMap.put("sLIKE", "包含");
        opMap.put("sNOTLIKE", "不包含");
        opMap.put("i==", "等于");
        opMap.put("i!=", "不等于");
        opMap.put("i<", "小于");
        opMap.put("i>", "大于");
        opMap.put("i<=", "小于等于");
        opMap.put("i>=", "大于等于");
    }

    /**
     * 初始化
     */
    @PostConstruct
    private void init() {
        initOpMap();
        File logsDir = new File(GatherCenter.gatherLogDir);
        if (!logsDir.exists()) {
            if (!logsDir.mkdirs() && log.isDebugEnabled()) {
                log.debug("mkdirs " + logsDir.getAbsolutePath() + " failed");
            }
        }
        File watchFile = new File(gatherConfigDir);
        if (!watchFile.exists()) {
            if (log.isErrorEnabled()) {
                log.error("gather config dir does not exists:" + watchFile.getAbsolutePath());
            }
            return;
        }
        // 加载采集脚本
        loadGatherScript(watchFile);
        // 增加文件监听
        fileChangeService.addFileChangeMonitor(watchFile);
        fileChangeService.addFileChangeListener((kind, file) -> {
            if (file.getParentFile().equals(watchFile)) {
                // 加载采集脚本
                loadGatherScript(watchFile);
            }
        });
    }

    /**
     * 加载采集脚本
     *
     * @param gatherFile 采集脚本存放目录
     */
    void loadGatherScript(File gatherFile) {
        dataCenter = new GatherXmlBean();
        dataCenter.setMainCategory(new ArrayList<>());
        File[] files = gatherFile.listFiles();
        if (files != null) {
            for (File file : files) {
                buildDataCenter(file);
            }
        }
        // 排序采集主分类
        dataCenter.buildComplete();
    }

    /**
     * 根据指定文件构建指标项
     *
     * @param file 指定的文件
     */
    private void buildDataCenter(File file) {
        try {
            if (!file.getName().endsWith(".xml")) {
                return;
            }
            JAXBContext ctx = JAXBContext.newInstance(GatherXmlMainCategoryBean.class);
            Unmarshaller unmarshaller = ctx.createUnmarshaller();
            GatherXmlMainCategoryBean mainCategory = (GatherXmlMainCategoryBean) unmarshaller.unmarshal(file);
            dataCenter.merge(mainCategory);
        } catch (Exception e) {
            if (log.isWarnEnabled()) {
                log.warn("parse gather xml file " + file.getAbsolutePath() + " failed", e);
            }
        }
    }

    /**
     * 向资产添加采集类型。
     *
     * @param assetType      资产类型
     * @param collectTypeSet 支持的采集类型
     */
    private void addCollectTypeToAssetType(String assetType, Set<Integer> collectTypeSet) {
        // SysType sysType = sysTypeRepository.findOneByName(assetType);
        if ("" != null) {
            Set<Integer> tmp = new HashSet<>(collectTypeSet);
            collectTypesBySystype.put(1L, tmp);
        } else {
            log.error("blchk xml has unknown asset types:" + assetType);
        }
        collectTypeSet.clear();
    }


    /**
     * 覆盖写文件，不存在则创建
     *
     * @param fileName 文件名
     * @param content  要写入的内容
     */
    private void writeFile(String fileName, String content) {
        FileOutputStream fos = null;
        PrintWriter pw = null;
        try {
            fos = new FileOutputStream(fileName);
            pw = new PrintWriter(fos);
            pw.write(content);
            pw.flush();
        } catch (FileNotFoundException e) {
            log.error("write file " + fileName + ":" + e);
        } finally {
            try {
                if (fos != null) {
                    fos.close();
                }
                if (pw != null) {
                    pw.close();
                }
            } catch (Exception e) {
                log.error("close file " + fileName + ":" + e);
            }
        }
    }

    /**
     * 根据设备类型id获取巡检项列表
     *
     * @param mainCategory 主类
     * @param category     次类
     * @return 巡检项分组的列表
     */
    public List<GatherGroup> getBaselineIndicators(String mainCategory, String category) {
        // BaselineTemplateType tempType =
        // inspTempTypeRepository.findOneById(tempTypeId);
        // String[] category = getCategory(tempType);
        try {
            return getGroups(mainCategory, category);
        } catch (Exception e) {
            if (log.isWarnEnabled()) {
                log.warn("getBaselineIndicators failed", e);
            }
            return null;
        }
    }

    /**
     * 根据设备类型id获取巡检项列表
     *
     * @param mainCategory 主类
     * @param category     次类
     * @param version      版本信息
     * @return 巡检项分组的列表
     */
    public List<GatherGroup> getBaselineIndicators(String mainCategory, String category, String version) {
        // BaselineTemplateType tempType =
        // inspTempTypeRepository.findOneById(tempTypeId);
        // String[] category = getCategory(tempType);
        if (version == null) {
            return null;
        }
        if (GatherCenter.CENTOS_5.equals(version)) {
            version = GatherCenter.CENTOS_6;
        }
        try {
            return getGroups(mainCategory, category, version);
        } catch (Exception e) {
            if (log.isWarnEnabled()) {
                log.warn("getBaselineIndicators failed", e);
            }
            return null;
        }
    }

    /**
     * 根据主类次类获取所有该文件下的所有巡检项信息
     *
     * @param mainCategory 主类
     * @param category     次类
     * @return 所有巡检项信息
     */
    public List<GatherDetail> getIndicatorsByMainAndCate(String mainCategory, String category) {
        List<GatherDetail> details = new ArrayList<>();
        if (null == mainCategory || null == category) {
            return details;
        }
        try {
            List<GatherGroup> groups = getGroups(mainCategory, category);
            if (null == groups) {
                throw new NullPointerException();
            }
            for (GatherGroup group : groups) {
                getIndicatorsInGroup(details, group);
            }
        } catch (Exception e) {
            if (log.isWarnEnabled()) {
                log.warn(String.format("failed to get indicators  mainCategory:%s, category:%s.", mainCategory,
                        category), e);
            }
        }
        return details;
    }

    /**
     * 根据主类、次类、第一层group名称获取所有该文件下的所有采集项信息
     *
     * @param mainCategory 主类
     * @param category     次类
     * @param firstGroup   第一级group名称
     * @return 所有巡检项信息
     */
    public List<GatherDetail> getIndicatorsByGroup(String mainCategory, String category, String firstGroup) {
        if (null != firstGroup) {
            firstGroup = firstGroup.toLowerCase();
        }
        List<GatherDetail> details = new ArrayList<>();
        if (null == mainCategory || null == category || null == firstGroup) {
            return details;
        }
        try {
            List<GatherGroup> groups = getGroups(mainCategory, category);
            if (null == groups) {
                throw new NullPointerException();
            }
            for (GatherGroup group : groups) {
                if (group.getName().contains(firstGroup)) {
                    getIndicatorsInGroup(details, group);
                    break;
                }
            }
        } catch (Exception e) {
            if (log.isWarnEnabled()) {
                log.warn(String.format("failed to get indicators mainCategory:%s, category:%s, group:%s.", mainCategory,
                        category, firstGroup), e);
            }
        }
        return details;
    }

    /**
     * 根据主类次类获取所有该文件下的所有巡检项信息
     *
     * @param mainCategory 主类
     * @param category     次类
     * @param version      os版本
     * @return 所有巡检项信息
     */
    public List<GatherDetail> getIndicatorsByMainAndCate(String mainCategory, String category, String version) {
        if (GatherCenter.CENTOS_5.equals(version)) {
            version = GatherCenter.CENTOS_6;
        }
        try {
            List<GatherDetail> details = new ArrayList<>();
            List<GatherGroup> groups = getGroups(mainCategory, category, version);
            if (groups != null && groups.size() > 0) {
                for (GatherGroup group : groups) {
                    getIndicatorsInGroup(details, group);
                }
            }
            return details;
        } catch (Exception e) {
            if (log.isWarnEnabled()) {
                log.warn("getBaselineIndicators failed", e);
            }
            return null;
        }
    }

    /**
     * 获取分组下的巡检项信息
     *
     * @param list  存入的list
     * @param group 分组信息
     */
    public void getIndicatorsInGroup(List<GatherDetail> list, GatherGroup group) {
        if (group != null) {
            if (group.getIndicator() != null) {
                list.addAll(group.getIndicator());
            }
            if (group.getGroup() != null && group.getGroup().size() > 0) {
                for (GatherGroup gro : group.getGroup()) {
                    getIndicatorsInGroup(list, gro);
                }
            }
        }
    }

    /**
     * 获取此监控项的分属层次 例如：OS层 硬件层
     *
     * @param itemkey 监控项item.key
     * @return 所属分组层
     */
    public String getMainCategoryGroup(String itemkey) {
        GatherXmlMainCategoryBean main = this.dataCenter.queryMainCategoryByItemKey(itemkey);
        if (main != null) {
            return main.getDisplay();
        }
        return "其他";
    }

    /**
     * 根据display获取BaselineXmlMainCategoryBean
     *
     * @param display display
     * @return 主类Bean
     */
    public List<GatherXmlMainCategoryBean> getMainCategoryByDisplay(String display) {
        return this.dataCenter.queryMainCategoryByDisplay(display);
    }

    /**
     * 获取此监控项的优先级
     *
     * @param itemkey 监控项item.key
     * @return 所属优先级
     */
    public Integer getMainCategoryPriority(String itemkey) {
        GatherXmlMainCategoryBean main = this.dataCenter.queryMainCategoryByItemKey(itemkey);
        if (main != null) {
            return main.getPriority();
        }
        return -1;
    }

    /**
     * 获取此监控项的分属分组
     *
     * @param itemkey 监控项item.key
     * @return BaselineGroup 巡检项所属分组
     */
    public GatherGroup getIndicatorGroup(String itemkey) {
        GatherDetail indicatorDetail = this.dataCenter.queryBaselineDetail(itemkey);
        if (indicatorDetail != null) {
            return indicatorDetail.getParentGroup();
        }
        return null;
    }

    /**
     * 获取此监控项的最外层分组
     *
     * @param itemKey 监控项item.key
     * @return BaselineGroup 巡检项所属分组
     */
    public GatherGroup getAncestorGroup(String itemKey) {
        GatherDetail indicatorDetail = this.dataCenter.queryBaselineDetail(itemKey);
        if (indicatorDetail != null) {
            return indicatorDetail.getParentGroup();
        }
        return null;
    }

    /**
     * 获取此监控项的最外层分组显示名
     *
     * @param itemKey 监控项item.key
     * @return display 最外层分组显示名
     */
    public String getAncestorDisplay(String itemKey) {
        GatherGroup group = getAncestorGroup(itemKey);
        if (group != null) {
            return group.getDisplay();
        }
        return "其它";
    }

    /**
     * 获取此监控项的巡检项数值的单位
     *
     * @param itemkey 监控项item.key
     * @return 单位(units)
     */
    public String getindicatorDetailUnits(String itemkey) {
        GatherDetail baselineDetail = this.dataCenter.queryBaselineDetail(itemkey);
        if (baselineDetail != null) {
            return baselineDetail.getUnits();
        }
        return "";
    }

    /**
     * 获取此监控项的巡检项数值的单位 单位设置在变量上 还未启用
     *
     * @param itemkey  监控项item.key, variable
     * @param variable 变量的名字
     * @return 单位(units)
     */
    public String getindicatorDetailUnits(String itemkey, String variable) {
        String units = "";
        GatherDetail baselineDetail = this.dataCenter.queryBaselineDetail(itemkey);
        if (baselineDetail == null) {
            return units;
        }
        List<GatherDetailOutput> outputs = baselineDetail.getOutput();
        if (outputs == null) {
            return units;
        }
        for (GatherDetailOutput out : outputs) {
            List<GatherDetailVariable> variables = out.getVariable();
            if (variables == null) {
                continue;
            }

            for (GatherDetailVariable var : variables) {
                if (var.getName().equals(variable)) {
                    return var.getUnits();
                }
            }
        }

        return units;
    }

    /**
     * 根据itemkey 获取BlchkDetail
     *
     * @param itemkey 巡检项
     * @return 巡检项对应的巡检详情
     */
    public GatherDetail getBlchkDetail(String itemkey) {
        return this.dataCenter.queryBaselineDetail(itemkey);
    }

    /**
     * 获取BaselineDetail
     *
     * @param mainCategory 主类，如host
     * @param category     次类，如aix
     * @param key          键，如CPU.CPU_load
     * @return 巡检项详情
     */
    public GatherDetail getBlchkDetail(String mainCategory, String category, String key) {
        try {
            List<GatherGroup> groups = getGroups(mainCategory, category);
            String[] keyNames = key.split("\\.");
            if (keyNames.length < 2) {
                return null;
            }
            GatherGroup parentGroup = null;
            if (null == groups) {
                throw new NullPointerException();
            }
            for (GatherGroup group : groups) {
                if (group.getName().equals(keyNames[0])) {
                    parentGroup = group;
                    break;
                }
            }
            if (parentGroup == null) {
                if (!key.contains(PRE_REQUISITE_GROUP)) {
                    return null;
                }
            }
            for (int i = 1; i < keyNames.length - 1; i++) {
                boolean found = false;
                if (parentGroup != null) {
                    for (GatherGroup group : parentGroup.getGroup()) {
                        if (group.getName().equals(keyNames[i])) {
                            parentGroup = group;
                            found = true;
                            break;
                        }
                    }
                }
                if (!found) {
                    return null;
                }
            }
            if (null == parentGroup) {
                throw new NullPointerException();
            }
            for (GatherDetail indicator : parentGroup.getIndicator()) {
                if (indicator.getName().equals(keyNames[keyNames.length - 1])) {
                    return indicator;
                }
            }
        } catch (Exception e) {
            // ignore
        }
        return null;
    }

    /**
     * 与getIndicators相同,用于页面展示 根据主类和次类获取BaselineXmlCategoryBean
     *
     * @param mainCategory 主类
     * @param category     次类
     * @return BaselineXmlCategoryBean实例
     */
    public GatherXmlCategoryBean getBaselineCategory(String mainCategory, String category) {
        // BaselineTemplateType tempType =
        // inspTempTypeRepository.findOneById(tempTypeId);
        // String[] category = getCategory(tempType);
        try {
            return getCategory(mainCategory, category);
        } catch (Exception e) {
            if (log.isWarnEnabled()) {
                log.warn("getIndicators failed", e);
            }
            return null;
        }
    }

    /**
     * 与getIndicators相同,用于页面展示 根据主类和次类获取BaselineXmlCategoryBean
     *
     * @param mainCategory 主类
     * @param category     次类
     * @param version      版本
     * @return BaselineXmlCategoryBean实例
     */
    public GatherXmlCategoryBean getBaselineCategory(String mainCategory, String category, String version) {
        // BaselineTemplateType tempType =
        // inspTempTypeRepository.findOneById(tempTypeId);
        // String[] category = getCategory(tempType);
        if (GatherCenter.CENTOS_5.equals(version)) {
            version = GatherCenter.CENTOS_6;
        }
        try {
            return getCategory(mainCategory, category, version);
        } catch (Exception e) {
            if (log.isWarnEnabled()) {
                log.warn("getIndicators failed", e);
            }
            return null;
        }
    }

    /**
     * 获取所有巡检项列表
     *
     * @return 巡检项集合。key：巡检项结构name；value：巡检项。
     */
    public Map<String, GatherDetail> getAllBaselineDetails() {
        Map<String, GatherDetail> map = new HashMap<>();
        // Iterator<BaselineTemplateType> iterator =
        // inspTempTypeRepository.findAll().iterator();
        // while(iterator.hasNext()) {
        // BaselineTemplateType sysType = iterator.next();
        // String[] category = getCategory(sysType);
        // List<IndicatorGroup> parts = getGroups(category[0], category[1]);
        // try {
        // BaselineXmlMainCategoryBean mainC = null;
        // // 次类别
        // BaselineXmlCategoryBean secondC = null;
        for (GatherXmlMainCategoryBean m : dataCenter.getMainCategory()) {
            for (GatherXmlCategoryBean s : m.getCategory()) {
                for (GatherGroup group : s.getGroup()) {
                    takeDetailsInGroup(group, null, map);
                }
            }
        }
        // } catch (Exception e) {
        // return null;
        // }
        // }
        return map;
    }

    /**
     * 递归从巡检项分组中获取巡检项
     *
     * @param group      巡检项分组
     * @param parentName 父分组结构名称
     * @param map        巡检项集合。
     */
    private void takeDetailsInGroup(GatherGroup group, String parentName, Map<String, GatherDetail> map) {
        if (null == parentName) {
            parentName = group.getName();
        } else {
            parentName = parentName + "." + group.getName();
        }
        List<GatherDetail> baselineList = group.getIndicator();
        if (null != baselineList && baselineList.size() > 0) {
            for (GatherDetail detail : baselineList) {
                String name = parentName + "." + detail.getName();
                map.put(name, detail);
            }
        }
        List<GatherGroup> groupList = group.getGroup();
        if (null != groupList && groupList.size() > 0) {
            for (GatherGroup child : groupList) {
                takeDetailsInGroup(child, parentName, map);
            }
        }
    }

    /**
     * 根据设备类型和巡检项获取巡检项的名称
     *
     * @param mainCategory 主类
     * @param category     次类
     * @param key          巡检项
     * @return 巡检项的名称，如果不存在，则返回null
     */
    public String getDisplayNameByKey(String mainCategory, String category, String key) {
        // String[] category = getCategory(tempType);
        GatherDetail detail = getBlchkDetail(mainCategory, category, key);
        if (detail == null) {
            return null;
        }
        return detail.getDisplay();
    }

    /**
     * 根据巡检项查找预巡检项
     *
     * @param mainCategory 主类
     * @param category     次类
     * @param key          巡检项
     * @return 如果找不到，则返回null
     */
    public String getPreKey(String mainCategory, String category, String key) {
        GatherDetail detail = getBlchkDetail(mainCategory, category, key);
        if (detail == null) {
            detail = getBlchkDetail(key);
        }
        if (detail == null) {
            return null;
        }
        String require = detail.getRequire();
        if (require == null) {
            return null;
        }
        return PRE_REQUISITE_GROUP + "." + require;
    }

    /**
     * 根据巡检项查找预巡检项
     *
     * @param mainCategory 主类
     * @param category     次类
     * @param key          巡检项
     * @return 如果找不到，则返回null
     */
    public List<String> getPreKeys(String mainCategory, String category, String key) {
        ArrayList<String> preKeys = new ArrayList<>();
        GatherDetail detail = getBlchkDetail(mainCategory, category, key);
        if (detail == null) {
            detail = getBlchkDetail(key);
        }
        if (detail == null) {
            return preKeys;
        }
        String require = detail.getRequire();
        if (require == null) {
            return preKeys;
        }
        String[] temps = require.split(REQUIRE_SPLIT);
        for (String temp : temps) {
            preKeys.add(PRE_REQUISITE_GROUP + "." + temp.trim());
        }
        return preKeys;
    }

    /**
     * 根据主类别、次类别、组名获取第一层组
     *
     * @param mainCategory 主类别
     * @param category     次类别
     * @param groupName    组名
     * @return 返回group列表，如果不存在，则返回null
     */
    public GatherGroup getFirstLevelGroup(String mainCategory, String category, String groupName) {
        GatherGroup result = null;
        try {
            List<GatherGroup> groups = getGroups(mainCategory, category);
            if (null == groups) {
                throw new NullPointerException();
            }
            for (GatherGroup group : groups) {
                if (group.getName().equalsIgnoreCase(groupName)) {
                    result = group;
                    break;
                }
            }
        } catch (Exception e) {
            mainCategory = mainCategory != null ? mainCategory : "";
            category = category != null ? category : "";
            groupName = groupName != null ? groupName : "";
            if (log.isDebugEnabled()) {
                String errMsg = "failed to get first level group, name: %s, category:%s, mainCategory:%s with %s.";
                log.debug(String.format(errMsg, groupName, category, mainCategory, e.toString()));
            }
        }
        return result;
    }

    /**
     * 根据主类别和次类别获取所有巡检项
     *
     * @param mainCategory 主类别
     * @param category     次类别
     * @param version      os版本
     * @return 返回group列表，如果不存在，则返回null
     */
    private List<GatherGroup> getGroups(String mainCategory, String category, String version) {
        if (GatherCenter.CENTOS_5.equals(version)) {
            version = GatherCenter.CENTOS_6;
        }
        try {
            // 次类别
            GatherXmlCategoryBean secondC = getCategory(mainCategory, category, version);
            if (secondC == null) {
                return null;
            }

            return secondC.getGroup();
        } catch (Exception e) {
            return null;
        }
    }

    /**
     * 根据主类别和次类别获取所有巡检项
     *
     * @param mainCategory 主类别
     * @param category     次类别
     * @return 返回group列表，如果不存在，则返回null
     */
    private List<GatherGroup> getGroups(String mainCategory, String category) {
        try {
            // 次类别
            GatherXmlCategoryBean secondC = getCategory(mainCategory, category);
            if (secondC == null) {
                return null;
            }

            return secondC.getGroup();
        } catch (Exception e) {
            return null;
        }
    }

    /**
     * 获取BaselineXmlCategoryBean
     *
     * @param mainCategory 主类，如host
     * @param category     次类，如aix
     * @return 巡检项详情
     */
    public GatherXmlCategoryBean getCategory(String mainCategory, String category) {
        try {
            GatherXmlMainCategoryBean mainC = dataCenter.queryMainCategory(mainCategory);
            if (mainC == null) {
                return null;
            }

            // 次类别
            return mainC.queryCategory(category);
        } catch (Exception e) {
            return null;
        }
    }

    /**
     * 获取BaselineXmlCategoryBean
     *
     * @param mainCategory 主类，如host
     * @param category     次类，如aix
     * @param version      os版本
     * @return 巡检项详情
     */
    public GatherXmlCategoryBean getCategory(String mainCategory, String category, String version) {
        if (GatherCenter.CENTOS_5.equals(version)) {
            version = GatherCenter.CENTOS_6;
        }
        try {
            GatherXmlMainCategoryBean mainC = dataCenter.queryMainCategory(mainCategory);
            if (mainC == null) {
                return null;
            }

            // 次类别
            return mainC.queryCategory(category, version);
        } catch (Exception e) {
            return null;
        }
    }

    /**
     * 获取BaselineXmlCategoryBean
     *
     * @param mainCategory 主类，如host
     * @param category     次类，如aix
     * @return 巡检项详情
     */
    public List<GatherXmlCategoryBean> getCategoryList(String mainCategory, String category) {
        try {
            GatherXmlMainCategoryBean mainC = dataCenter.queryMainCategory(mainCategory);
            if (mainC == null) {
                return null;
            }

            // 次类别
            return mainC.queryCategoryList(category);
        } catch (Exception e) {
            return null;
        }
    }

    /**
     * 根据次类名称判断配置文件中是否存在
     *
     * @param category 次类名称（资源类型名称）
     * @return true 或 false
     */
    public boolean isExistCategory(String category) {
        List<GatherXmlMainCategoryBean> list = getDataCenter().getMainCategory();
        for (GatherXmlMainCategoryBean main : list) {
            for (GatherXmlCategoryBean cate : main.getCategory()) {
                if (cate.getName().equals(category)) {
                    return true;
                }
            }
        }
        return false;
    }

    /**
     * 获取indicatorMainMap
     *
     * @return indicatorMainMap
     */
    public Map<String, GatherXmlMainCategoryBean> queryIndicatorMainMap() {
        return dataCenter.getIndicatorMainMap();
    }

    /**
     * 基线配置文件信息转换英文
     *
     * @param categoryBean 配置文件信息
     * @param blchkGroup   分组配置文件信息
     * @param localeStr    中英文环境信息
     */
    public void baselineToEnglish(GatherXmlCategoryBean categoryBean, GatherGroup blchkGroup, String localeStr) {
        if ("en_US".equals(localeStr)) {
            if (categoryBean != null && categoryBean.getGroup() != null && categoryBean.getGroup().size() > 0) {
                for (GatherGroup gro1 : categoryBean.getGroup()) {
                    if (gro1 == null) {
                        continue;
                    }

                    if (gro1.getGroup() == null || gro1.getGroup().size() < 1) {
                        continue;
                    }
                    for (GatherGroup gro2 : gro1.getGroup()) {

                        if (gro2.getIndicator() == null || gro2.getIndicator().size() < 1) {
                            continue;
                        }
                        for (GatherDetail item : gro2.getIndicator()) {
                            if (item.getDisplayEn() != null) {
                                item.setDisplay(item.getDisplayEn());
                            }
                            if (item.getOutput() == null || item.getOutput().size() < 1) {
                                continue;
                            }
                            for (GatherDetailOutput out : item.getOutput()) {
                                if (out.getVariable() == null || out.getVariable().size() < 1) {
                                    continue;
                                }
                                for (GatherDetailVariable var : out.getVariable()) {
                                    if (var.getValueDescriptionEn() != null) {
                                        var.setValueDescription(var.getValueDescriptionEn());
                                    }
                                    if (var.getDynamicIndicatorDisplayEn() != null) {
                                        var.setDynamicIndicatorDisplay(var.getDynamicIndicatorDisplayEn());
                                    }
                                }
                            }
                        }
                    }
                }
            }
            if (blchkGroup != null && blchkGroup.getGroup() != null && blchkGroup.getGroup().size() > 0) {

                if (blchkGroup.getGroup() != null && blchkGroup.getGroup().size() > 0) {
                    for (GatherGroup gro2 : blchkGroup.getGroup()) {

                        if (gro2.getIndicator() == null || gro2.getIndicator().size() < 1) {
                            continue;
                        }
                        for (GatherDetail item : gro2.getIndicator()) {
                            if (item.getDisplayEn() != null) {
                                item.setDisplay(item.getDisplayEn());
                            }
                            if (item.getOutput() == null || item.getOutput().size() < 1) {
                                continue;
                            }
                            for (GatherDetailOutput out : item.getOutput()) {
                                if (out.getVariable() == null || out.getVariable().size() < 1) {
                                    continue;
                                }
                                for (GatherDetailVariable var : out.getVariable()) {
                                    if (var.getValueDescriptionEn() != null) {
                                        var.setValueDescription(var.getValueDescriptionEn());
                                    }
                                    if (var.getDynamicIndicatorDisplayEn() != null) {
                                        var.setDynamicIndicatorDisplay(var.getDynamicIndicatorDisplayEn());
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }
    }

    /**
     * 初始化方法。
     *
     * @return 构造操作符翻译对象。
     */
    public Map<String, String> generalOperatorMap() {
        Map<String, String> operatorMap = new HashMap<>();
        operatorMap.put("==", "等于");
        operatorMap.put("!=", "不等于");
        operatorMap.put("<", "小于");
        operatorMap.put("<=", "小于等于");
        operatorMap.put(">", "大于");
        operatorMap.put(">=", "大于等于");
        operatorMap.put("LIKE", "包含");
        operatorMap.put("NOTLIKE", "不包含");
        operatorMap.put("IN", "包含");
        operatorMap.put("NOTIN", "不包含");
        operatorMap.put("NOP", "任何");
        operatorMap.put("v<", "小于");
        operatorMap.put("v<=", "小于等于");
        operatorMap.put("v>", "大于");
        operatorMap.put("v>=", "大于等于");
        operatorMap.put("o==", "等于");
        operatorMap.put("o!=", "不等于");
        operatorMap.put("o<", "小于");
        operatorMap.put("o>", "大于");
        operatorMap.put("o<=", "小于等于");
        operatorMap.put("o>=", "大于等于");
        operatorMap.put("oIN", "包含");
        operatorMap.put("oNOTIN", "不包含");
        operatorMap.put("s==", "等于");
        operatorMap.put("sLIKE", "包含");
        operatorMap.put("sNOTLIKE", "不包含");
        operatorMap.put("i==", "等于");
        operatorMap.put("i!=", "不等于");
        operatorMap.put("i<", "小于");
        operatorMap.put("i>", "大于");
        operatorMap.put("i<=", "小于等于");
        operatorMap.put("i>=", "大于等于");
        operatorMap = Collections.unmodifiableMap(operatorMap);
        return operatorMap;
    }

    /**
     * 获取indicatorMap
     *
     * @return indicatorMap
     */
    public Map<String, GatherDetail> queryIndicatorMap() {
        return dataCenter.getIndicatorMap();
    }

    public GatherXmlBean getDataCenter() {
        return dataCenter;
    }

    public void setDataCenter(GatherXmlBean dataCenter) {
        this.dataCenter = dataCenter;
    }

    /**
     * 根据资产类型id获取其对应的采集类型
     *
     * @param sysTypeId 资产类型id
     * @return 采集类型set
     */
    public Set<Integer> getCollectTypesBySystype(Long sysTypeId) {
        Set<Integer> assetTaskTypes = collectTypesBySystype.get(sysTypeId);
        if (assetTaskTypes == null) {
            assetTaskTypes = new HashSet<>();
            assetTaskTypes.add(GatherCenter.TYPE_INFREQUENT_CHANGE_ITEM);
        }
        return assetTaskTypes;
    }
}
